package com.cavy.platform.server.domain.job;

import com.cavy.platform.server.dto.JobSubscribeKey;
import com.cavy.platform.server.service.ContainerLogTailerManager;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Data
@Slf4j
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = ContainerLogSubscribeKey.class)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ContainerLogSubscribeKey.class, name = "subscribe"),
        @JsonSubTypes.Type(value = ContainerLogUnSubscribeKey.class, name = "unsubscribe")
})
public class ContainerLogSubscribeKey extends JobSubscribeKey {
    public static final String DEFAULT_TYPE = "subscribe";
    protected String type = "subscribe";
    protected String stage;
    protected int containerIndex;
    protected int dependencyIndex;

    public ContainerLogSubscribeKey(String workSpace, String project, String pipeline, String number
            , String stage, int containerIndex, int dependencyIndex) {
        super(workSpace, project, pipeline, number);
        this.stage = stage;
        this.containerIndex = containerIndex;
        this.dependencyIndex = dependencyIndex;
    }

    public ContainerLogSubscribeKey() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        ContainerLogSubscribeKey that = (ContainerLogSubscribeKey) o;
        return containerIndex == that.containerIndex &&
                dependencyIndex == that.dependencyIndex &&
                Objects.equals(type, that.type) &&
                Objects.equals(stage, that.stage);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), type, stage, containerIndex, dependencyIndex);
    }

    /**
     * 处理请求
     * 1,对session进行处理
     * 2，如果该容器没有tailer则创建一个tailer
     * 3，如果该容器没有订阅了，则移除tailer
     *
     * @param subscribe     订阅列表
     * @param session       当前请求会话
     * @param tailerManager 日志输出管理器
     */
    public void handler(ConcurrentHashMap<ContainerLogSubscribeKey, List<Session>> subscribe, Session session, ContainerLogTailerManager tailerManager) {
        List<Session> sessions = subscribe.get(this);
        if (sessions == null || sessions.isEmpty()) {
            sessions = new ArrayList<>();
        }
        sessions.add(session);
        subscribe.put(this, sessions);
        tailerManager.create(this);
    }
}
